#include <sys/system.h>
#include <sys/string.h>
#include <gal/ptgui.h>
#include <gal/surface.h>
#include <gal/font.h>
#include <gal/dc.h>

ptgui_dc_t *ptgui_dc_begin_drawing(ptgui_surface_t *owner)
{
	ptgui_dc_t *dc;

	/* adjudge owner */
	if (owner == PT_NULL) {
		return PT_NULL;
	}

	dc = (ptgui_dc_t *)pt_malloc(sizeof(ptgui_dc_t));

	dc->owner = owner;
	
	dc->font = ptgui_font_default();
	dc->fg_color = ptgui_surface_map_color(dc->owner, 255, 0, 0);

	return dc;
}

void ptgui_dc_end_drawing(ptgui_dc_t *dc)
{
	if (dc == PT_NULL) {
		return;
	}

	pt_free(dc);
}

void ptgui_dc_destory(struct ptgui_dc *dc)
{
	if (dc == PT_NULL) {
		return;
	}

	pt_free(dc);
}

void ptgui_dc_draw_point(struct ptgui_dc *dc, pt_int16_t x, pt_int16_t y)
{
	if (dc == PT_NULL) {
		return;
	}

	ptgui_surface_draw_pixel(dc->owner, x, y, dc->fg_color);
}

void ptgui_dc_set_fg_color(struct ptgui_dc *dc, ptgui_color_t color)
{
	pt_uint32_t map_color;

	map_color = ptgui_surface_map_color(dc->owner, PTGUI_RGB_R(color), PTGUI_RGB_G(color), PTGUI_RGB_B(color));

	dc->fg_color = map_color;
}

void ptgui_dc_set_fg_color_rgb(struct ptgui_dc *dc, pt_uint8_t r, pt_uint8_t g, pt_uint8_t b)
{
	pt_uint32_t map_color;

	map_color = ptgui_surface_map_color(dc->owner, r, g, b);

	dc->fg_color = map_color;
}

void ptgui_dc_set_bg_color(struct ptgui_dc *dc, ptgui_color_t color)
{
	pt_uint32_t map_color;

	map_color = ptgui_surface_map_color(dc->owner, PTGUI_RGB_R(color), PTGUI_RGB_G(color), PTGUI_RGB_B(color));

	dc->bg_color = map_color;
}

ptgui_color_t ptgui_dc_get_fg_color(struct ptgui_dc *dc)
{
	pt_uint8_t r;
	pt_uint8_t g;
	pt_uint8_t b;

	ptgui_surface_unmap_color(dc->fg_color, dc->owner, &r, &g, &b);

	return PTGUI_RGB(r, g, b);
}

ptgui_color_t ptgui_dc_get_bg_color(struct ptgui_dc *dc)
{
	pt_uint8_t r;
	pt_uint8_t g;
	pt_uint8_t b;

	ptgui_surface_unmap_color(dc->bg_color, dc->owner, &r, &g, &b);

	return PTGUI_RGB(r, g, b);
}

void ptgui_dc_draw_text(struct ptgui_dc *dc, const char *text, struct ptgui_rect *rect)
{
	pt_uint32_t len;
	struct ptgui_font *font;
#ifdef PTGUI_FEATHER_USING_FONTHZ
	struct ptgui_font *gb2312_font;
#endif
	struct ptgui_rect text_rect;
	const pt_uint8_t *text2;

	PT_ASSERT(dc != PT_NULL);

	font = dc->font;
	text2 = (const pt_uint8_t *)text;
	if (font == PT_NULL) {
		/* use system default font */
		font = ptgui_font_default();
	}

#ifdef PTGUI_FEATHER_USING_FONTHZ
	gb2312_font = ptgui_font_refer("hz", font->height);
	if (gb2312_font == PT_NULL) {
		gb2312_font = ptgui_font_refer("hz", 16);
	}
#endif

	/* text2 align */
	ptgui_font_get_metrics(font, text2, &text_rect);
	ptgui_rect_moveto_align(rect, &text_rect, dc->text_align);

#ifdef PTGUI_FEATHER_USING_FONTHZ
	while (*text2) {
		len = 0;
		while (*(text2 + len) < 0x80 && *(text2 + len))
			len ++;
		if (len > 0) {
			ptgui_font_draw(font, dc, text2, len, &text_rect);

			text2 += len;
		}

		len = 0;
		while (*(text2 + len) > 0x80)
			len ++;
		if (len > 0) {
			ptgui_font_draw(gb2312_font, dc, text2, len, &text_rect);

			text2 += len;
		}
	}

	ptgui_font_derefer(gb2312_font);
#else
	len = pt_strlen((const char*)text);
	ptgui_font_draw(font, dc, text2, len, &text_rect);
#endif
}

pt_bool_t ptgui_dc_get_visible(struct ptgui_dc *dc)
{
	return PT_FALSE;
}